home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / fbm.uni / fbm.lha / src / fledge.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-25  |  8.5 KB  |  363 lines

  1. /*****************************************************************
  2.  * fledge.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989,1990 by Gary Sherwin & Michael Mauldin.
  5.  * Permission is granted to use this file in whole or in part for
  6.  * any purpose, educational, recreational or commercial, provided
  7.  * that this copyright notice is retained unchanged.  This software
  8.  * is available to all free of charge by anonymous FTP and in the
  9.  * UUNET archives.
  10.  *
  11.  * fledge.c:
  12.  *
  13.  * CONTENTS
  14.  *    findedge_fbm (&image, beta)
  15.  *
  16.  * EDITLOG
  17.  *    LastEditDate = Mon Jun 25 00:05:13 1990 - Michael Mauldin
  18.  *    LastFileName = /usr2/mlm/src/misc/fbm/fledge.c
  19.  *
  20.  * HISTORY
  21.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  22.  *    Package for Release 1.0
  23.  *
  24.  * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  25.  *    Beta release (version 0.9) mlm@cs.cmu.edu
  26.  *
  27.  * 21-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  28.  *    Created with help from Gary Sherwin of Westinghouse Elec.
  29.  *****************************************************************/
  30.  
  31. # include <stdio.h>
  32. # include <math.h>
  33. # include <ctype.h>
  34. # include "fbm.h"
  35.  
  36. /****************************************************************
  37.  * findedge_fbm: determine whether image is in color, and call the
  38.  *            appropriate edge detection routine.
  39.  ****************************************************************/
  40.  
  41. #ifndef lint
  42. static char *fbmid =
  43. "$FBM fledge.c <1.0> 25-Jun-90  (C) 1989,1990 by Michael Mauldin, source \
  44. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  45. #endif
  46.  
  47. findedge_fbm (input, output, beta)
  48. FBM *input, *output;
  49. int beta;
  50. {
  51.   if (input->hdr.planes == 1)
  52.   { return (findedge_bw (input, output, beta)); }
  53.   else
  54.   { return (findedge_bw (input, output, beta)); }
  55. }
  56.  
  57. /****************************************************************
  58.  * findedge_bw: use a digital Laplacian filter to edge detect a BW image
  59.  ****************************************************************/
  60.  
  61. findedge_bw (input, output, beta)
  62. FBM *input, *output;
  63. int beta;
  64. { register unsigned char *bmp, *obm;
  65.   register int i, j, rowlen, w, h;
  66.   int new, sum;
  67.   int bf, wf, tf; /* white and black pixel counters */
  68.  
  69. /* Filter Chip
  70. *
  71. *
  72. * UL, UC, UR
  73. * CL, CC, CR
  74. * BL, BC, BR
  75. *
  76. */
  77.  
  78.   if (input->hdr.planes != 1)
  79.   { fprintf (stderr, "findedge_bw: can't process color images\n");
  80.     return (0);
  81.   }
  82.  
  83.   fprintf (stderr, "Edge detect BW, beta %d\n", beta);
  84.  
  85.   /* Allocate output */
  86.   output->hdr = input->hdr;
  87.   alloc_fbm (output);
  88.  
  89.   w = input->hdr.cols;
  90.   h = input->hdr.rows;
  91.   rowlen = input->hdr.rowlen;
  92.  
  93.   /* Set pixel counters for image statistics */
  94.   bf = wf = tf = 0;
  95.  
  96.   /* Compute outer border of pixels */
  97.     /* Compute Top Line U of Pixels */
  98.       /* Compute ULPixel */
  99.    
  100.   j=0;
  101.   { bmp = &(input->bm[j*rowlen]);
  102.     obm = &(output->bm[j*rowlen]);
  103.     
  104.     i=0;
  105.     { sum = 0;
  106.       sum = sum + (bmp[i]*(-3)     + bmp[i+1]       );
  107.       sum = sum + (bmp[i+rowlen]   + bmp[i+rowlen+1]);
  108.       sum = (sum * 8) / 3;
  109.  
  110.       if (sum > beta) { new = BLACK; bf++; }
  111.       else { new = WHITE; wf++; }
  112.  
  113.       tf++;
  114.  
  115.       obm[i] = new;
  116.  
  117.     }
  118.  
  119.     /* Compute URPixel */
  120.    
  121.     i=w;
  122.     { sum = 0;
  123.       sum = sum + (bmp[i-1]*(-3)     + bmp[i]         ) ;
  124.       sum = sum + (bmp[i+rowlen-1]   + bmp[i+rowlen]  ) ;
  125.       sum = (sum * 8) / 3;
  126.  
  127.       if (sum > beta) { new = BLACK; bf++; }
  128.       else { new = WHITE; wf++; }
  129.  
  130.       tf++;
  131.  
  132.       obm[i] = new;
  133.  
  134.     }
  135.  
  136.    /* Compute Rest of U1 Line */
  137.   
  138.     for (i=1; i < w-1; i++)
  139.     { sum = 0;
  140.       sum = sum + (bmp[i-1]*(-5)   + bmp[i]        + bmp[i+1]       ) ;
  141.       sum = sum + (bmp[i+rowlen-1] + bmp[i+rowlen] + bmp[i+rowlen+1]) ;
  142.       sum = (sum * 8) / 5;
  143.  
  144.       if (sum > beta) { new = BLACK; bf++; }
  145.         else { new = WHITE; wf++; }
  146.  
  147.       tf++;
  148.  
  149.       obm[i] = new;
  150.  
  151.     }
  152.   }
  153.  
  154.   /* Compute Left and Right borders */
  155.   
  156.   for (j=1; j < h-1; j++)
  157.   { bmp = &(input->bm[j*rowlen]);
  158.     obm = &(output->bm[j*rowlen]);
  159.  
  160.     /* Compute L Pixel */   
  161.     i=0;
  162.     { sum = 0;
  163.       sum = sum + (bmp[i-rowlen]   + bmp[i-rowlen+1]) ;
  164.       sum = sum + (bmp[i]*(-5)     + bmp[i+1]       ) ;
  165.       sum = sum + (bmp[i+rowlen]   + bmp[i+rowlen+1]) ;
  166.       sum = (sum * 8) / 5;
  167.  
  168.       if (sum > beta) { new = BLACK; bf++; }
  169.       else { new = WHITE; wf++; }
  170.  
  171.       tf++;
  172.  
  173.       obm[i] = new;
  174.  
  175.     }
  176.  
  177.  
  178.     /* Compute R1Pixel */
  179.     i=w;
  180.     { sum = 0;
  181.       sum = sum + (bmp[i-rowlen-1]   + bmp[i-rowlen]  ) ;
  182.       sum = sum + (bmp[i-1]          + bmp[i]*(-5)    ) ;
  183.       sum = sum + (bmp[i+rowlen-1]   + bmp[i+rowlen]  ) ;
  184.       sum = (sum * 8) / 5;
  185.  
  186.       if (sum > beta) { new = BLACK; bf++; }
  187.       else { new = WHITE; wf++; }
  188.  
  189.       tf++;
  190.  
  191.       obm[i] = new;
  192.  
  193.     }
  194.   }
  195.  
  196.     /* Compute Bottom Line B of Pixels */
  197.     /* Compute BL Pixel */ 
  198.   j=h;
  199.   { bmp = &(input->bm[j*rowlen]);
  200.     obm = &(output->bm[j*rowlen]);
  201.     
  202.     i=0;
  203.     { sum = 0;
  204.       sum = sum + (bmp[i-rowlen]   + bmp[i-rowlen+1]) ;
  205.       sum = sum + (bmp[i]*(-3)     + bmp[i+1]       ) ;
  206.       sum = (sum * 8) / 3;
  207.  
  208.       if (sum > beta) { new = BLACK; bf++; }
  209.       else { new = WHITE; wf++; }
  210.  
  211.       tf++;
  212.  
  213.       obm[i] = new;
  214.  
  215.     }
  216.  
  217.        /* Compute BR Pixel */
  218.  
  219.     i=w;
  220.     { sum = 0;
  221.       sum = sum + (bmp[i-rowlen-1]   + bmp[i-rowlen]  ) ;
  222.       sum = sum + (bmp[i-1]          + bmp[i]*(-3)    ) ;
  223.       sum = (sum * 8) / 3;
  224.  
  225.       if (sum > beta) { new = BLACK; bf++; }
  226.       else { new = WHITE; wf++; }
  227.  
  228.       tf++;
  229.  
  230.       obm[i] = new;
  231.  
  232.     }
  233.  
  234.       /* Compute Rest of B1 Line */
  235.  
  236.     for (i=1; i < w-1; i++)
  237.     { sum = 0;
  238.       sum = sum + (bmp[i-rowlen-1]   + bmp[i-rowlen]   + bmp[i-rowlen+1]) ;
  239.       sum = sum + (bmp[i-1]          + bmp[i]*(-5)     + bmp[i+1]       ) ;
  240.       sum = (sum * 8) / 5;
  241.  
  242.       if (sum > beta) { new = BLACK; bf++; }
  243.       else { new = WHITE; wf++; }
  244.  
  245.       tf++;
  246.  
  247.       obm[i] = new;
  248.  
  249.     }
  250.   }
  251.  
  252.   /* Compute Main Image Body */
  253.  
  254.   for (j=1; j < h-1; j++)
  255.   { bmp = &(input->bm[j*rowlen]);
  256.     obm = &(output->bm[j*rowlen]);
  257.     
  258.     for (i=1; i < w-1; i++)
  259.     { sum = 0;
  260.       sum = sum + (bmp[i-rowlen-1]   + bmp[i-rowlen]   + bmp[i-rowlen+1]) ;
  261.       sum = sum + (bmp[i-1]          + bmp[i]*(-8)     + bmp[i+1]       ) ;
  262.       sum = sum + (bmp[i+rowlen-1]   + bmp[i+rowlen]   + bmp[i+rowlen+1]) ;
  263.  
  264.       if (sum > beta) { new = BLACK; bf++; }
  265.       else { new = WHITE; wf++; }
  266.  
  267.       tf++;
  268.  
  269.       obm[i] = new;
  270.  
  271.     }
  272.   }
  273.  
  274.   fprintf (stderr, "Edge detection complete for slope of %2d for %d pixels.\n", beta, tf);
  275.   fprintf (stderr, "Detected %d white pixels and %d black pixels.\n", bf, wf);
  276.  
  277.   return (1);
  278. }
  279.  
  280. /****************************************************************
  281.  * findedge_clr: use a digital Laplacian filter to edge detect a CLR image
  282.  ****************************************************************/
  283.  
  284. findedge_clr (input, output, beta)
  285. FBM *input, *output;
  286. double beta;
  287. { register unsigned char *bmp, *obm, *avg;
  288.   register int i, j, k, rowlen, plnlen, w, h, p, sum;
  289.   int new, delta, beta100 = beta * 100;
  290.   unsigned char *gray;
  291.  
  292.   fprintf (stderr, "Sharpen color, beta %lg\n", beta);
  293.  
  294.   /* Allocate output */
  295.   output->hdr = input->hdr;
  296.   alloc_fbm (output);
  297.  
  298.   w = input->hdr.cols;
  299.   h = input->hdr.rows;
  300.   p = input->hdr.planes;
  301.   rowlen = input->hdr.rowlen;
  302.   plnlen = input->hdr.plnlen;
  303.   
  304.   /* Calculate the intensity plane */
  305.   gray = (unsigned char *) malloc (plnlen);
  306.  
  307.   for (j=0; j<h; j++)  
  308.   { bmp = &(input->bm[j*rowlen]);
  309.     avg = &(gray[j*rowlen]);    
  310.  
  311.     for (i=0; i<w; i++)
  312.     { sum = 0;
  313.       for (k=0; k<p; k++)
  314.       { sum += bmp[i+k*plnlen]; }
  315.       avg[i] = sum/p;
  316.     }
  317.   }
  318.   
  319.   /* Copy edges directly */
  320.   for (k=0; k<p; k++)
  321.   {  for (j=0; j<h; j++)
  322.     { output->bm[k*plnlen + j*rowlen] =
  323.     input->bm[k*plnlen + j*rowlen];
  324.       output->bm[k*plnlen + j*rowlen + w-1] =
  325.     input->bm[k*plnlen + j*rowlen + w-1];
  326.     }
  327.   
  328.     for (i=0; i<w; i++)
  329.     { output->bm[k*plnlen + i] =
  330.     input->bm[k*plnlen + i];
  331.       output->bm[k*plnlen + (h-1)*rowlen + i] =
  332.     input->bm[k*plnlen + (h-1)*rowlen + i];
  333.     }
  334.   }
  335.  
  336.   for (j=1; j < h-1; j++)
  337.   { avg = &(gray[j*rowlen]);
  338.     
  339.     for (i=1; i < w-1; i++)
  340.     { sum = avg[i-rowlen-1] +     avg[i-rowlen] + avg[i-rowlen+1] +
  341.         avg[i-1]        - 8 * avg[i]        + avg[i+1]        +
  342.         avg[i+rowlen-1] +     avg[i+rowlen] + avg[i+rowlen+1];
  343.  
  344.       for (k=0; k<p; k++)
  345.       { bmp =  &(input->bm[k*plnlen + j*rowlen + i]);
  346.         obm = &(output->bm[k*plnlen + j*rowlen + i]);
  347.         
  348.     if (sum < 0)
  349.     { delta = - (beta100 * *bmp * -sum / (8*100)); }
  350.     else
  351.     { delta = beta100 * *bmp * sum / (8*100); }
  352.   
  353.     new = *bmp - delta;
  354.   
  355.     if (new < BLACK) new = BLACK;
  356.     else if (new > WHITE) new = WHITE;
  357.     
  358.     *obm = new;
  359.       }
  360.     }
  361.   }
  362. }
  363.